import requests
import time
import threading

# 同步锁，多线程时有用
_lock = threading.Lock()

IP_SERVER_HOST: str = "http://118.89.40.12:8001"
IP_MAX_USAGE: int = 5


class IP:
    def __init__(self, max_number: int):
        while True:
            try:
                headers = {"pw": "123465"}
                r = requests.get(IP_SERVER_HOST + "/ip", headers=headers)
                rj = r.json()
                if rj["ret"] == 0:
                    self._addr: str = rj['data']
                    self._max_number: int = max_number
                    self._assign_number: int = 0
                    self._used_number: int = 0
                    return
            except Exception as e:
                pass
            time.sleep(1)

    def assign(self) -> bool:
        """
        分配IP，增加分配次数
        :return: 成功返回True,失败返回False
        """
        if self._assign_number < self._max_number:
            self._assign_number += 1
            return True
        return False

    def get_addr(self) -> str:
        """
        获取ip地址
        :return: 返回ip地址
        """
        return self._addr

    def use(self):
        """
        请求结束之后，记录使用次数
        :return:
        """
        self._used_number += 1
        if self._used_number >= self._max_number:
            self._remove_ip()

    def _remove_ip(self) -> None:
        try:
            headers = {"pw": "123465"}
            requests.get("http://%s:42234/change-ip" % self._addr, timeout=10, headers=headers)
        except Exception as e:
            print(e)


class IpPool:
    _ip: IP = None

    @staticmethod
    def get() -> IP:
        try:
            _lock.acquire()
            if IpPool._ip is None or not IpPool._ip.assign():
                IpPool._ip = IP(IP_MAX_USAGE)
                IpPool._ip.assign()
        finally:
            _lock.release()

        return IpPool._ip


if __name__ == '__main__':
    """
    测试多线程分配IP
    """


    class RunThread(threading.Thread):
        def __init__(self):
            threading.Thread.__init__(self)

        def run(self):
            for i in range(3):
                ip = IpPool.get()
                print(ip.get_addr())
                time.sleep(3)
                ip.use()


    thread_list = []
    for i in range(7):
        t = RunThread()
        thread_list.append(t)

    for t in thread_list:
        t.start()

    for t in thread_list:
        t.join()

    print("完成")
